<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>jssdk</title>
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <!--浏览器缩放-->
  <meta name="viewport" content="width=device-width,initial-scale=1.0">
  <!--引入jssdk-->
  <script src="http://res.wx.qq.com/open/js/jweixin-1.2.0.js"></script>
  <!--引入网络工具-->
  <script src="https://unpkg.com/axios/dist/axios.min.js"></script>
  <!--调试工具-->
  <script type="text/javascript" src="https://cdn.bootcdn.net/ajax/libs/vConsole/3.3.4/vconsole.min.js"></script>
  <!--hash1签名工具-->
  <script src="https://cdn.bootcdn.net/ajax/libs/jshashes/1.0.8/hashes.min.js"></script>
</head>
<body>
<!--按钮-->
<button id="bioassayAuthentication">人脸识别</button>
<button id="enterpriseContact">通讯录</button>

<script type="text/javascript">

  //接口地址
  let baseUrl = "http://192.168.0.1:9999/wechat/cgi-bin";
  //政务微信corpid
  let corpid = '***';

  //应用secret
  let corpsecret = '***';

  //应用id
  let agentid = ***;

  //console控制台
  let vConsole = new VConsole();

  //步骤
  //1、获取accessToken 需缓存
  //根据corpid和应用secret获取accessToken，需要缓存7000秒
  function getAccessToken() {
    return axios.get(baseUrl + '/gettoken', {
      params: {
        'corpid': corpid, 'corpsecret': corpsecret
      }
    });
  }

  //2、获取jsapiTicket/jsAgentApiTicket 需要缓存7000秒
  //注意初始化config和agentConfig的接口地址不一样
  //获取jsapiTicket
  function getJsApiTickect(url, accessToken) {
    return axios.get(baseUrl + url, {
      params: {
        'access_token': accessToken
      }
    })
  }

  //3、计算签名
  /**
   * 生成签名的时间戳
   * @return {数字串}
   */
  function createTimestamp() {
    return parseInt(new Date().getTime() / 1000);
  }

  /**
   * 生成签名的随机串
   * @return {字符串}
   */
  function createNonceStr() {
    return Math.random().toString(36).substr(2, 15)
  }

  /**
   * 对参数对象进行字典排序
   * @param  {对象} args 签名所需参数对象
   * @return {字符串}    排序后生成字符串
   */
  function raw(args) {
    var keys = Object.keys(args)
    keys = keys.sort()
    var newArgs = {}
    keys.forEach(function (key) {
      newArgs[key.toLowerCase()] = args[key]
    })

    var string = ''
    for (var k in newArgs) {
      string += '&' + k + '=' + newArgs[k]
    }
    string = string.substr(1)
    return string
  }

  /**
   * noncestr随机字符串，一般自己生成
   * jsapi_ticket 从政务微信服务器或者自己的缓存中
   * timestamp时间戳自己生成
   * url当前页面的url，一定要动态获取，千万不要 hardcode
   * 然后再按照字典排序，进行排序 jsapi_ticket&noncestr&timestamp&url
   * 最后sha1 加密
   */
  function getSignature(jsapi_ticket, nonceStr, timestamp) {
    let ret = {
      jsapi_ticket: jsapi_ticket,
      nonceStr: nonceStr,
      timestamp: timestamp,
      url: location.href.split("#")[0]
    }
    let str = raw(ret);
    console.log(str);
    let SHA1 = new Hashes.SHA1;
    return SHA1.hex(str);
  }

  //4、初始化jssdk config/agentConfig
  async function init() {
    //获取token
    let accessTokenResp = await getAccessToken();
    console.log(accessTokenResp.data)
    let accessToken = accessTokenResp.data.access_token;

    //获取jsApiTicket
    let jsApiTicketResp = await getJsApiTickect('/get_jsapi_ticket', accessToken);
    console.log(jsApiTicketResp.data)
    let jsApiTicket = jsApiTicketResp.data.ticket;
    let nonceStr = createNonceStr();
    let timestamp = createTimestamp();
    console.log(`jsApiTicket:${jsApiTicket}`)
    //计算config签名
    let signature = getSignature(jsApiTicket, nonceStr, timestamp);

    //获取agentJsapiTicket
    let agentJsApiTicketResp = await getJsApiTickect('/ticket/get?type=agent_config', accessToken);
    console.log(agentJsApiTicketResp.data);
    let agentJsApiTicket = agentJsApiTicketResp.data.ticket;
    console.log(`agentJsApiTicket:${agentJsApiTicket}`)

    //计算agentConfig签名
    let agentSignature = getSignature(agentJsApiTicket, nonceStr, timestamp);

    //初始化jssdk
    wx.config({
      beta: true,// 调用wx.invoke形式的接口值时，该值必须为true。
      debug: false, // 开启调试模式,调用的所有api的返回值会在客户端alert出来，若要查看传入的参数，可以在pc端打开，参数信息会通过log打出，仅在pc端时才会打印。
      appId: corpid, // 必填，企业微信的cropID
      timestamp: timestamp, // 必填，生成签名的时间戳
      nonceStr: nonceStr, // 必填，生成签名的随机串
      signature: signature,// 必填，签名，见附录1
      jsApiList: ['checkJsApi', 'agentConfig', 'selectEnterpriseContact', 'bioassayAuthentication'] // 必填，需要使用的JS接口列表，所有JS接口列表见附录
    });
    //初始化成功回调
    wx.ready(function () {
      // config信息验证后会执行ready方法，所有接口调用都必须在config接口获得结果之后，config是一个客户端的异步操作，所以如果需要在页面加载时就调用相关接口，则须把相关接口放在ready函数中调用来确保正确执行。对于用户触发时才调用的接口，则可以直接调用，不需要放在ready函数中。
      console.log('wx ready');
      //初始化agentConfig
      wx.invoke("agentConfig", {
        agentid: agentid, // 必填，企业应用的agentid
        corpid: corpid,  // 必填，企业微信的corpid
        timestamp: timestamp, // 必填，生成签名的时间戳,int类型, 如 1539100800
        nonceStr: nonceStr, // 必填，生成签名的随机串
        signature: agentSignature,// 必填，签名，见附录5
      }, function (res) {
        console.log(res);
        //这里可以调用用户数据接口
        if (res.err_msg != "agentConfig:ok") {
          //错误处理
          return;
        }
      });
    });
    //jssdk初始化失败
    wx.error(function (res) {
      // config信息验证失败会执行error函数，如签名过期导致验证失败，具体错误信息可以打开config的debug模式查看，也可以在返回的res参数中查看，对于SPA可以在这里更新签名。
      console.log(res);
    });
  }
  //调用初始化的方法
  init();
  //5、使用jssdk
  //人脸识别认证
  //打开政务微信通讯录
  //监听按钮点击事件
  document.getElementById("enterpriseContact").addEventListener("click", function () {
    wx.invoke("selectEnterpriseContact", {
        "fromDepartmentId": -1,// 必填，-1表示打开的通讯录从自己所在部门开始展示, 0表示从最上层开始
        "mode": "single",// 必填，选择模式，single表示单选，multi表示多选
        "type": ['department','user'],// 必填，选择限制类型，指定department、user中的一个或者多个
        "selectedDepartmentIds": [],// 非必填，已选部门ID列表。用于多次选人时可重入
        "selectedUserIds": [],// 非必填，已选用户ID列表。用于多次选人时可重入
        "includeExternalContact": 1 //非必填，是否包含外部联系人。
      }, function (res) {
        console.log(res);
        if (res.err_msg == "selectEnterpriseContact:ok") {
          if (typeof res.result == 'string') {
            res.result = JSON.parse(res.result) //由于目前各个终端尚未完全兼容，需要开发者额外判断result类型以保证在各个终端的兼容性
          }
          var selectedDepartmentList = res.result.departmentList;// 已选的部门列表
          for (var i = 0; i < selectedDepartmentList.length; i++) {
            var department = selectedDepartmentList[i];
            var departmentId = department.id;// 已选的单个部门ID
            var departemntName = department.name;// 已选的单个部门名称
          }
          var selectedUserList = res.result.userList; // 已选的成员列表
          for (var i = 0; i < selectedUserList.length; i++) {
            var user = selectedUserList[i];
            var userId = user.id; // 已选的单个成员ID
            var userName = user.name;// 已选的单个成员名称
            var userAvatar = user.avatar;// 已选的单个成员头像
            var userIsExternal = user.isExternal; //已选的单个成员是否外部联系人
          }
        }
      }
    );
  });
  document.getElementById("bioassayAuthentication").addEventListener("click", function () {
    alert('bioassayAuthentication')
    wx.invoke('bioassayAuthentication', {
      name: '', // 姓名
      idcard: '' // 身份证号
    }, function (res) {
      console.log(res);
      if (res.err_msg == "bioassayAuthentication:ok") {
        var code = res.code; //检测成功
      } else {
        //错误处理
      }
      console.log(res);
    });
  });
</script>
</body>
</html>
